//
//  TradeSocketMessage.m
//  EFSMobile
//
//  Created by Chuan on 12/10/15.
//  Copyright © 2015 Elephants Financial Service. All rights reserved.
//

#import "EFSNFXGTradeSocketMessage.h"

#import "EFSNFXGTradeDefine.h"

#import <YTXCommonSocket/CommonSocket.h>
#import <CocoaAsyncSocket/GCDAsyncSocket.h>

typedef struct {
    unsigned char bStartFlag;   //协议包起始标志 0xFF
    unsigned char bVer;         //版本号
    unsigned char bEncryptFlag; //加密标志(如果不加密,则为0)
    unsigned char bFrag;        //是否有包分片(1 有包分片 0 无包分片)
    unsigned short wLen;        //总包长
    unsigned short wCmd;        //命令号
    unsigned short wSeq;        //包的序列号,业务使用
    unsigned short wCrc;        // Crc16校验码
    unsigned int dwSID;         //会话ID
    unsigned short wTotal;      //有包分片时，分片总数
    unsigned short wCurSeq;     //有包分片时，分片序号
} NtPkgHead;

@implementation EFSNFXGTradeSocketMessage

- (NSInteger)headerLength {
    return sizeof(NtPkgHead);
}

- (NSData *)startFlagData {
    return [NSData dataWithBytes:"\xFF" length:1];
}

- (UInt16)heartBeatCommand {
    return EFSNFXGTradeSocketCommandHeartBeat;
}

- (NSTimeInterval)heartBeatInterval {
    return 10.0f;
}

- (UInt16)bodyLength:(NSDictionary *)header {
    return [header[@"wLen"] unsignedShortValue] - [self headerLength];
}

- (NSData *)packData:(NSString *)stringInfo
         withCommand:(UInt16)command
              andSeq:(UInt16)seq;
{
    NSError *error = nil;
    NSData *packData = [stringInfo dataUsingEncoding:NSUTF8StringEncoding];

    // Log.d(@"%s, %lu", [packData bytes], [packData length]);

    if (error) {
        return nil;
    }

    NtPkgHead nt;

    nt.bStartFlag = 0xff;
    nt.bVer = 0;
    nt.bEncryptFlag = 0;
    nt.bFrag = 0;
    nt.wCrc = 0;
    nt.dwSID = 0;
    nt.wTotal = 0;
    nt.wCurSeq = 0;
    nt.wLen = NSSwapHostShortToBig(packData.length + [self headerLength]);
    nt.wSeq = NSSwapHostShortToBig(seq);
    nt.wCmd = NSSwapHostShortToBig(command);

    NSMutableData *resp = [[NSMutableData alloc] initWithCapacity:nt.wLen];

    [resp appendBytes:&nt length:sizeof(NtPkgHead)];
    // Log.d(@"send bytes: %@", resp);

    [resp appendBytes:[packData bytes] length:[packData length]];
    return resp;
}

- (CommonSocketData *)unpackDataHeader:(NSData *)data {
    //    if (data.length != 19) {
    //        Log.d(@"Error data");
    //        abort();
    //    }
    UInt16 workidx = 0;

    // declare separator
    // Log.d(@"Data is: %@", data);

    EXACT_DATA(UInt8, bVer)
    EXACT_DATA(UInt8, bEncryptFlag)
    EXACT_DATA(UInt8, bFrag)
    EXACT_DATA(UInt16, wLen)
    EXACT_DATA(UInt16, wCmd)
    EXACT_DATA(UInt16, wSeq)
    EXACT_DATA(UInt16, wStatusCode)
    EXACT_DATA(UInt32, dwSID)
    EXACT_DATA(UInt16, wTotal)
    EXACT_DATA(UInt16, wCurSeq)

    wCmd = NSSwapHostShortToBig(wCmd);
    wSeq = NSSwapHostShortToBig(wSeq);
    wLen = NSSwapHostShortToBig(wLen);
    wStatusCode = NSSwapHostShortToBig(wStatusCode);
    wTotal = NSSwapHostShortToBig(wTotal);
    wCurSeq = NSSwapHostShortToBig(wCurSeq);
    
    CommonSocketData *socketData = [CommonSocketData new];
    socketData.wCmd = wCmd;
    socketData.wSeq = wSeq;
    socketData.wTotal =  wTotal;
    socketData.wCurSeq = wCurSeq;
    socketData.wBodyLength = wLen - [self headerLength];
    
    return socketData;
}

- (CommonSocketData *)formatSocketData:(CommonSocketData *)data withBody:(id)body
{
    CommonSocketData *result = [data copy];
    result.info = body;
    return result;
}

@end
